"""
商品相关数据模型

以商品为核心的数据模型设计，包括商品基本信息、原始素材、处理后素材等。
"""

from datetime import datetime
from typing import Dict, Any, Optional, List
import json

from sqlalchemy import Column, Integer, String, Float, Text, Boolean, ForeignKey, Index, DateTime, Enum
from sqlalchemy.orm import relationship, backref
import enum

from .base import BaseModel, JSONField


class ProductStatus(enum.Enum):
    """商品状态枚举"""
    DRAFT = "draft"              # 草稿
    ACTIVE = "active"            # 活跃
    INACTIVE = "inactive"        # 停用
    ARCHIVED = "archived"        # 归档


class ProductType(enum.Enum):
    """商品类型枚举"""
    CLOTHING = "clothing"        # 服装
    ACCESSORIES = "accessories"  # 配饰
    SHOES = "shoes"             # 鞋类
    BAGS = "bags"               # 包类
    OTHER = "other"             # 其他


class Product(BaseModel):
    """
    商品表 - 核心实体
    
    存储商品的基本信息，作为整个系统的核心实体。
    """
    
    __tablename__ = 'products'
    
    # 基本信息
    name = Column(String(255), nullable=False, index=True)
    title = Column(String(500), nullable=True)  # 商品标题/描述
    sku = Column(String(100), unique=True, nullable=False, index=True)
    brand = Column(String(100), nullable=True, index=True)
    category = Column(String(100), nullable=True, index=True)
    product_type = Column(Enum(ProductType), nullable=False, default=ProductType.OTHER)
    
    # 状态信息
    status = Column(Enum(ProductStatus), nullable=False, default=ProductStatus.DRAFT)
    is_active = Column(Boolean, default=True, nullable=False)
    
    # 商品属性
    price = Column(Float, nullable=True)  # 价格
    cost = Column(Float, nullable=True)   # 成本
    weight = Column(Float, nullable=True) # 重量(克)
    
    # 尺寸信息 (JSON格式存储)
    dimensions = Column(JSONField, nullable=True)  # {"length": 10, "width": 5, "height": 2}
    
    # 颜色和材质
    colors = Column(JSONField, nullable=True)      # ["红色", "蓝色", "黑色"]
    materials = Column(JSONField, nullable=True)   # ["棉", "聚酯纤维"]
    
    # 标签和关键词
    tags = Column(JSONField, nullable=True)        # ["时尚", "休闲", "夏季"]
    keywords = Column(Text, nullable=True)         # 搜索关键词
    
    # 描述信息
    description = Column(Text, nullable=True)      # 商品描述
    features = Column(JSONField, nullable=True)    # 特性列表
    
    # 供应商信息
    supplier_name = Column(String(255), nullable=True)
    supplier_code = Column(String(100), nullable=True)
    
    # 库存信息
    stock_quantity = Column(Integer, default=0)
    min_stock_level = Column(Integer, default=0)
    
    # 销售信息
    launch_date = Column(DateTime, nullable=True)  # 上市日期
    discontinue_date = Column(DateTime, nullable=True)  # 停产日期
    
    # 扩展属性 (JSON格式，用于存储自定义属性)
    custom_attributes = Column(JSONField, nullable=True)
    
    # 关联关系
    raw_materials = relationship("ProductRawMaterial", back_populates="product", cascade="all, delete-orphan")
    materials = relationship("ProductMaterial", back_populates="product", cascade="all, delete-orphan")
    material_categories = relationship("ProductMaterialCategory", back_populates="product", cascade="all, delete-orphan")
    outputs = relationship("ProductOutput", back_populates="product", cascade="all, delete-orphan")
    
    # 索引
    __table_args__ = (
        Index('idx_product_sku_status', 'sku', 'status'),
        Index('idx_product_brand_category', 'brand', 'category'),
        Index('idx_product_type_status', 'product_type', 'status'),
    )
    
    def to_dict(self) -> Dict[str, Any]:
        """转换为字典格式"""
        result = super().to_dict()
        
        # 处理枚举类型
        result['status'] = self.status.value if self.status else None
        result['product_type'] = self.product_type.value if self.product_type else None
        
        # 处理JSON字段
        result['dimensions'] = self.get_dimensions()
        result['colors'] = self.get_colors()
        result['materials_list'] = self.get_materials()
        result['tags'] = self.get_tags()
        result['features'] = self.get_features()
        result['custom_attributes'] = self.get_custom_attributes()
        
        return result
    
    def get_dimensions(self) -> Dict[str, Any]:
        """获取尺寸信息"""
        if self.dimensions:
            return json.loads(self.dimensions) if isinstance(self.dimensions, str) else self.dimensions
        return {}
    
    def get_colors(self) -> List[str]:
        """获取颜色列表"""
        if self.colors:
            return json.loads(self.colors) if isinstance(self.colors, str) else self.colors
        return []
    
    def get_materials(self) -> List[str]:
        """获取材质列表"""
        if self.materials:
            return json.loads(self.materials) if isinstance(self.materials, str) else self.materials
        return []
    
    def get_tags(self) -> List[str]:
        """获取标签列表"""
        if self.tags:
            return json.loads(self.tags) if isinstance(self.tags, str) else self.tags
        return []
    
    def get_features(self) -> List[str]:
        """获取特性列表"""
        if self.features:
            return json.loads(self.features) if isinstance(self.features, str) else self.features
        return []
    
    def get_custom_attributes(self) -> Dict[str, Any]:
        """获取自定义属性"""
        if self.custom_attributes:
            return json.loads(self.custom_attributes) if isinstance(self.custom_attributes, str) else self.custom_attributes
        return {}
    
    def set_dimensions(self, length: float = None, width: float = None, height: float = None):
        """设置尺寸信息"""
        dims = self.get_dimensions()
        if length is not None:
            dims['length'] = length
        if width is not None:
            dims['width'] = width
        if height is not None:
            dims['height'] = height
        self.dimensions = json.dumps(dims, ensure_ascii=False)
    
    def add_color(self, color: str):
        """添加颜色"""
        colors = self.get_colors()
        if color not in colors:
            colors.append(color)
            self.colors = json.dumps(colors, ensure_ascii=False)
    
    def add_material(self, material: str):
        """添加材质"""
        materials = self.get_materials()
        if material not in materials:
            materials.append(material)
            self.materials = json.dumps(materials, ensure_ascii=False)
    
    def add_tag(self, tag: str):
        """添加标签"""
        tags = self.get_tags()
        if tag not in tags:
            tags.append(tag)
            self.tags = json.dumps(tags, ensure_ascii=False)
    
    def set_custom_attribute(self, key: str, value: Any):
        """设置自定义属性"""
        attrs = self.get_custom_attributes()
        attrs[key] = value
        self.custom_attributes = json.dumps(attrs, ensure_ascii=False)
    
    def get_custom_attribute(self, key: str, default: Any = None) -> Any:
        """获取自定义属性"""
        attrs = self.get_custom_attributes()
        return attrs.get(key, default)
    
    def get_total_raw_materials_count(self) -> int:
        """获取原始素材总数"""
        return len(self.raw_materials)
    
    def get_total_processed_materials_count(self) -> int:
        """获取已处理素材总数"""
        return len(self.materials)
    
    def get_total_outputs_count(self) -> int:
        """获取成品总数"""
        return len(self.outputs)
    
    def get_materials_by_category(self, category: str) -> List['ProductMaterial']:
        """根据分类获取素材"""
        return [material for material in self.materials 
                if any(cat.category_name == category for cat in material.categories)]
    
    def is_available(self) -> bool:
        """检查商品是否可用"""
        return (self.status == ProductStatus.ACTIVE and 
                self.is_active and 
                (self.discontinue_date is None or self.discontinue_date > datetime.now()))
    
    def __repr__(self):
        return f"<Product(id={self.id}, sku='{self.sku}', name='{self.name}', status='{self.status.value if self.status else None}')>"
